home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
PET
/
S-Super PET
/
(s)t4.d64
/
FIB.ASM
< prev
next >
Wrap
Assembly Source File
|
2009-01-18
|
6KB
|
187 lines
; Written by Avygdor Moise
; York University
; Rm 340 Petrie Building
; Tel 667-3954
xref printf_,getrec_,cnvif_,isdigit_,cnvf2s_,stoi_,fload_
service_ set $32
return macr
clr service_
rts
endm
ldu #$8000 ;allow lots of space for data stack...
loop
jsr read ;input an integer from terminal into 'd'
quif eq
jsr fibonacci ;call fibonacci with argument in D
jsr print ;return result
endloop
return
; If [D] = 0 1 2 3 4 5 6 ....
; then [,U....3,u] = 1 1 2 3 5 8 13 ....
fibonacci pshs d ;save input parameter
cmpd #2 ;assume [d] = [a,b] > 0
if lt ;if d < 2 then
ldb #1
pshu d
clrb ; answer = 1
pshu d ;
else ;else
subd #1 ;
bsr fibonacci ; fibonacci(D-1)
subd #1 ; +
bsr fibonacci ; fibonacci(D-2)
bsr double_add ; answer = --------------
endif ;endif
;
puls d ;restore input parameter unchanged
rts ;return from subroutine
;The following function will replace two 32 bit numbers on user stack
;by their sum.
double_add ldd 2,u ; D <-- Least Significant Word 1
addd 6,u ; D <-- D + Least Significant Word 2
std 6,u ; Least Significant Word 2 <-- D
;
ldd 4,u ; D <-- Most Significant Word 2
;
adcb 1,u ;
adca ,u ; D <-- D + Most Significant Word 1
; + carry if any
std 4,u ; Most Significant Word 2 <-- D
leau 4,u ;remove Double Word from the stack
rts ;result is Double Word on User stack
request_data fcc "%nEnter an integer please : "
fcb 0
buffer rmb 81
read equ * ;read a number from the terminal then
;return its 16 bit binary representation in Reg D
ldd #request_data
jsr printf_
ldd #80
pshs d ;argument = 'buffer length'
ldd #buffer ;argument = address of 'buffer'
jsr getrec_ ;get a line from terminal into 'buffer'
leas 2,s ;drop used argument 'buffer length'
ldx #buffer
loop ;find the first digit
pshs b
clra
ldb ,x+
pshs x
jsr isdigit_
puls x
puls b
quif ne
decb ;if not digit then reduce count by 1
until eq ;quit if counter exhausted
lbeq read ;request another data
leax -1,x ;x points to start of data
clr b,x ;convert data to string
pshs x
loop
clra
ldb ,x+
quif eq
pshs x
jsr isdigit_
puls x
if eq
ldb #$ff
else
clrb
endif
until ne
puls x
lbne read ;re-enter the data
clr 5,x ;make sure that there aren't too many digits
tfr x,d
jsr stoi_ ;d will contain the resulting integer
rts
result fcc "%nFibonacci number = %s%n"
fcb 0
answer rmb 20
print equ * ;print answer on ,U to terminal
jsr cnv_di_2f ;convert double integer on U to float
tfr u,d
jsr fload_ ;transfer floating point number to acc1
leau 5,u ;remove number off user stack
ldd #answer
pshs d
jsr cnvf2s_ ;answer$ = str$(acc1)
ldd #result
jsr printf_
leas 2,s
rts
cnv_di_2f equ * ;convert unsigned double integer to float
;floating point format ....
; SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM
; S = sign 1 = negative, 0 = positive
; E = exponent in excess of 128
; M = mantissa , left justified, first bit assumed to be 1
ldb #32 ;counter = 32 bits to convert
;need to left justify number
loop
tst ,u ;quit when most significant bit = 1
quif lt
asl 3,u ; C <-- xxxxxxxx <-- 0
rol 2,u ; C <-- xxxxxxxx <-- C
rol 1,u
rol 0,u
;effective result is a multiplication by two
;so we need to adjust exponent later !!!
decb
until eq ;all bits shifted ==> integer = 0
if ne ;i.e. if b=0 then integer=0
addb #128 ;exponent in excess of 128
asrb ; S --> xxxxxxx --> C
if cs
lda #128
ora ,u
else
lda #127
anda ,u
endif
sta ,u
andb #127 ;remove sign bit
pshu b
else
clr ,-u
endif
rts
end